package com.yhgarden.bbs.service.impl.system;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yhgarden.bbs.entity.system.*;
import com.yhgarden.bbs.entity.vo.menu.RoleIdMenuIdsVo;
import com.yhgarden.bbs.entity.vo.menu.RoleMenuTitleVo;
import com.yhgarden.bbs.entity.vo.systemUser.SystemUserRolesVo;
import com.yhgarden.bbs.mapper.system.MenuMapper;
import com.yhgarden.bbs.mapper.system.RoleMenuMapper;
import com.yhgarden.bbs.model.constants.YhbbsConstants;
import com.yhgarden.bbs.model.enums.StatusCode;
import com.yhgarden.bbs.model.helper.Pager;
import com.yhgarden.bbs.model.helper.SortPointer;
import com.yhgarden.bbs.model.response.BaseResponse;
import com.yhgarden.bbs.service.api.system.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;

@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;
    
    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private ExecutorService executorService;

    @Override
    public BaseResponse createOrUpdate(HttpSession session, Menu menu) throws Exception {
        SystemUserRolesVo systemUserRolesVo = (SystemUserRolesVo) session.getAttribute(YhbbsConstants.SYSTEM_USER_SESSION_KEY);
        SystemUser sessionUser = systemUserRolesVo.getSystemUser();
        String userId = sessionUser.getId();
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        if(menu.getId() == null){
            String uuid = UUID.randomUUID().toString();
            menu.setId(uuid);
            menu.setCreatedBy(userId);
            menuMapper.create(menu);
        }else {
            menu.setUpdatedBy(userId);
            menuMapper.update(menu);
        }
        executorService.submit(()->{
            String pid = menu.getPid();
            if(pid != null){
                Menu pMenu = new Menu();
                pMenu.setId(pid);
                pMenu.setHasChildren(true);
                menuMapper.update(pMenu);
            }
        });
        response.setData(menu);
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse handleRoleMenu(RoleIdMenuIdsVo roleIdMenuIdsVo) throws Exception {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        String roleId = roleIdMenuIdsVo.getRoleId();
        //先删除后写入
        RoleMenu roleMenu = new RoleMenu();
        roleMenu.setRoleId(roleId);
        roleMenuMapper.deleteByExample(roleMenu);
        //批量写入
        List<RoleMenu> roleMenuList = new ArrayList<>();
        List<String> menuIds = roleIdMenuIdsVo.getMenuIds();
        menuIds.forEach(menuId->{
            RoleMenu roleMenuTemp = new RoleMenu();
            String uuid = UUID.randomUUID().toString();
            roleMenuTemp.setId(uuid);
            roleMenuTemp.setRoleId(roleId);
            roleMenuTemp.setMenuId(menuId);
            roleMenuList.add(roleMenuTemp);
        });
        roleMenuMapper.batchCreate(roleMenuList);
        return response;
    }

    @Override
    public BaseResponse getById(String id) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        Menu menu = menuMapper.getById(id);
        response.setData(menu);
        return response;
    }

    @Override
    public BaseResponse getByRoleId(String roleId) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        List<RoleMenuTitleVo> menuList = roleMenuMapper.getByRoleId(roleId);
        response.setData(menuList);
        return response;
    }


    @Override
    public BaseResponse getByIdMoreDetail(String id) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        Menu menu = menuMapper.getByIdMoreDetail(id);
        response.setData(menu);
        return response;
    }


    @Override
    public BaseResponse getByPid(String pid) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        List<Menu> menus = menuMapper.getByPid(pid);
        executorService.submit(()->{
           if(menus.size() == 0){
               Menu pMenu = new Menu();
               pMenu.setId(pid);
               pMenu.setHasChildren(false);
               menuMapper.update(pMenu);
           }
        });
        response.setData(menus);
        return response;
    }


    @Override
    public BaseResponse query(Menu menu) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        Pager pager = menu.getPager();
        SortPointer sortPointer = menu.getSortPointer();
        PageHelper.startPage(pager.getCurrentPage(),pager.getPageSize());
        List<Menu> menuList = menuMapper.query(menu,sortPointer.getOrder(),sortPointer.getField());
        PageInfo result = new PageInfo<Menu>(menuList);
        response.setData(result);
        return response;
    }


    @Override
    public BaseResponse queryForList(Menu menu) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        Pager pager = menu.getPager();
        SortPointer sortPointer = menu.getSortPointer();
        if(sortPointer == null){
            sortPointer = new SortPointer();
        }
        PageHelper.startPage(pager.getCurrentPage(),pager.getPageSize());
        List<Menu> menuList = menuMapper.queryForList(menu,sortPointer.getOrder(),sortPointer.getField());
        PageInfo result = new PageInfo<Menu>(menuList);
        response.setData(result);
        return response;
    }


    @Override
    public BaseResponse queryMoreDetail(Menu menu) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        Pager pager = menu.getPager();
        SortPointer sortPointer = menu.getSortPointer();
        if(sortPointer == null){
            sortPointer = new SortPointer();
        }
        PageHelper.startPage(pager.getCurrentPage(),pager.getPageSize());
        List<Menu> menuList = menuMapper.queryMoreDetail(menu,sortPointer.getOrder(),sortPointer.getField());
        PageInfo result = new PageInfo<Menu>(menuList);
        response.setData(result);
        return response;
    }


    @Override
    public BaseResponse delete(String id) {
        BaseResponse response = new BaseResponse(StatusCode.SUCCESS);
        menuMapper.delete(id);
        return response;
    }

    @Override
    public List<Menu> getByRolesAndUserId(List<Role> roleList, String userId) {
        List<String> roleIds = new ArrayList<>();
        roleList.forEach(role -> {
            roleIds.add(role.getId());
        });
        return menuMapper.getByRolesAndUserId(roleIds,userId);
    }

}
